#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <windows.h> 
#include <WinBase.h>
#include <io.h>



struct Stu
{
	char num[30];//学号
	char name[30];//名字
	double grade[11];//1-6存各科分数 7存平均 8存总分 9学校排名 10 班级排名	
};


struct Sys
{
	Stu* data; 
	int sz;	  //当前人数
	int cap; //容量
};



//函数接口
//------------------------------------------
//添加学生
void Add(Sys& p);
//删除学生
void Del(Sys& p);
//查找学生信息
void Search(Sys& p);
//修改学生信息
void Modify(Sys& p);
//打印系统中的内容
void Show(Sys& p);
//保存学生信息
void Save(Sys& p);
//导出排名,0班级,1年级
void GetRank(Sys& p, int choice);
//获取进步名单
void GetGo(Sys& p);
//-------------------------------------------------------------------


void menu()
{
	printf("-------------\n");
	printf("1.添加成绩  |\n");
	printf("2.删除学生  |\n");
	printf("3.查找学生  |\n");
	printf("4.修改成绩  |\n");
	printf("5.成绩展示  |\n");
	printf("6.进步名单  |\n");
	printf("7.成绩保存  |\n");
	printf("8.全班排名  |\n");
	printf("9.全校排名  |\n");
	printf("0.退出程序  |\n");
	printf("-------------\n");
}n




//实例化一个对象
void Init(Sys& p)
{
	p.sz = 0;
	Stu* ptr = (Stu*)calloc(3, sizeof(Stu));
	p.data = ptr;
	p.cap= 3;
}


//销毁
void Destroy(Sys* p)
{
	free(p->data); //释放顺序表连续的空间
	p->data = NULL; 
	p->cap = 0; //容量0
	p->sz = 0; //大小标0
	p = NULL; //指针制空
}


//自动扩容
void Check(Sys& p)
{
	if (p.sz == p.cap)
	{
		Stu* ptr = (Stu*)realloc(p.data, (p.cap + 2) * sizeof(Stu));
		if (ptr == NULL)
		{
			printf("扩容失败");
			return;
		}
		p.data = ptr;
		p.cap += 2;
	}
}



//加获取各种排名
void GetGrade(Sys& p, int choice)
{
	if (choice == 0)
	{
		//读数据
		FILE* pf = fopen("ClassOneGrade.txt", "r");
		if (pf == NULL)
		{
			printf("打开失败\n");
		}
		else
		{
			Stu t;
			int i = 0;
			while (fscanf(pf, "%s %s %lf %lf %lf %lf %lf %lf \n", t.num, t.name, &(t.grade[1]),
				&(t.grade[2]), &(t.grade[3]), &(t.grade[4]), &(t.grade[5]), &(t.grade[6])) != EOF)
			{
				//增容
				Check(p);

				//平均分,总分
				double sum = t.grade[1] + (t.grade[2]) + (t.grade[3]) + (t.grade[4]) + (t.grade[5]) + (t.grade[6]);
				t.grade[8] = sum;
				t.grade[7] = sum / 6;
				p.data[i] = t;
				p.sz++;//容量
				i++;
			}
			fclose(pf);
			pf = NULL;
		}
	}
	else if (choice == 1)
	{
		//读数据
		FILE* pf = fopen("SchoolGrade.txt", "r");
		if (pf == NULL)
		{
			printf("打开失败\n");
		}
		else
		{
			Stu t;
			int i = 0;
			while (fscanf(pf, "%s %s %lf %lf %lf %lf %lf %lf \n", t.num, t.name, &(t.grade[1]),
				&(t.grade[2]), &(t.grade[3]), &(t.grade[4]), &(t.grade[5]), &(t.grade[6])) != EOF)
			{
				//增容
				Check(p);

				//平均分,总分
				double sum = t.grade[1] + (t.grade[2]) + (t.grade[3]) + (t.grade[4]) + (t.grade[5]) + (t.grade[6]);
				t.grade[8] = sum;
				t.grade[7] = sum / 6;
				p.data[i] = t;
				p.sz++;//容量
				i++;
			}
			fclose(pf);
			pf = NULL;
		}
	}
}




//导入数据到文件中
void GetData(Sys& p)
{
	while (1)
	{
		printf("若录入班级成绩请输入1 ,若录入年级成绩请输出2 !\n");
		int in;
		scanf("%d", &in);

		if (in == 1)
		{
			GetGrade(p,0);//班级成绩,0为获取班级成绩
			system("cls");
			return;
		}
		else if (in== 2)
		{
			GetGrade(p,1);//全校成绩,1为获取全校成绩
			system("cls");
			return;
		}
		else
		{
			printf("您输入的数字有误!!\n");
			system("cls");
		}
	}
}






//添加学生
void Add(Sys& p)
{
	Check(p);

	printf("请输入名字: ");
	scanf("%s", p.data[p.sz].name);
	printf("请输入学号: ");
	scanf("%s", p.data[p.sz].num);
	printf("请输入高数成绩: ");
	scanf("%lf", &(p.data[p.sz].grade[1]));
	printf("请输入线性成绩: ");
	scanf("%lf", &(p.data[p.sz].grade[2]));
	printf("请输入英语成绩: ");
	scanf("%lf", &(p.data[p.sz].grade[3]));
	printf("请输入历史成绩: ");
	scanf("%lf", &(p.data[p.sz].grade[4]));
	printf("请输入数电成绩: ");
	scanf("%lf", &(p.data[p.sz].grade[5]));
	printf("请输入体育成绩: ");
	scanf("%lf", &(p.data[p.sz].grade[6]));


	double sum = p.data[p.sz].grade[1] + p.data[p.sz].grade[2] + p.data[p.sz].grade[3] + p.data[p.sz].grade[4]
		+ p.data[p.sz].grade[5] + p.data[p.sz].grade[6];

	p.data[p.sz].grade[8] = sum;
	p.data[p.sz].grade[7] = sum/6;

	p.sz++;//容量增加
}



//删除学生
void Del(Sys& p)
{
	char name[20];

	//删除
	//找到要删除的人
	printf("请输入要删除的人的名字:>");
	scanf("%s", name);

	bool ok = false;
	int pos = 0;
	for (int i = 0; i < p.sz; i++)
	{
		if (strcmp(p.data[i].name, name) == 0)
		{
			ok = true;
			pos = i;
			break;
		}
	}

	if (!ok)
	{
		printf("删除学生不存在\n");
		return;
	}

	for (int i = pos; i < p.sz - 1; i++)
	{
		p.data[i] = p.data[i + 1];
	}
	p.sz--;
	printf("删除成功\n");
}



//查找学生信息
void Search(Sys& p)
{
	printf("请输入查找同学的学号!\n");
	char num[20];
	scanf("%s", num);
	bool ok = false;
	int pos = 0;
	for (int i = 0; i < p.sz; i++)
	{
		if (strcmp(p.data[i].num,num) == 0)
		{
			ok = true;
			pos = i;
			break;
		}
	}

	if (!ok)
	{
		printf("删除学生不存在\n");
		return;
	}
	else
	{
		printf("%-20s  %-4s  %-4s  %-4s  %-4s  %-4s  %-4s   %-4s  %-4s  %-4s\n", "学号", "名字", "高数", "线代", "英语", "历史",
			"数电", "体育", "均分", "总分");
		printf("%-20s %-4s %-4.1lf %-4.1lf %-4.1lf %-4.1lf %-4.1lf %-4.1lf %-4.1lf %-4.1lf\n", p.data[pos].num,
			p.data[pos].name,
			p.data[pos].grade[1],
			p.data[pos].grade[2],
			p.data[pos].grade[3],
			p.data[pos].grade[4],
			p.data[pos].grade[5],
			p.data[pos].grade[6],
			p.data[pos].grade[7],
			p.data[pos].grade[8]);

		printf("\n\n");
	}

}





//修改学生信息
void Modify(Sys& p)
{
	printf("请输入修改同学的学号!\n");
	char num[20];
	scanf("%s", num);
	bool ok = false;
	int pos = 0;
	for (int i = 0; i < p.sz; i++)
	{
		if (strcmp(p.data[i].num, num) == 0)
		{
			ok = true;
			pos = i;
			break;
		}
	}

	if (!ok)
	{
		printf("此学生不存在\n");
		return;
	}

	scanf("%s", p.data[pos].num);
	printf("请输入高数成绩: ");
	scanf("%lf", &(p.data[pos].grade[1]));
	printf("请输入线性成绩: ");
	scanf("%lf", &(p.data[pos].grade[2]));
	printf("请输入英语成绩: ");
	scanf("%lf", &(p.data[pos].grade[3]));
	printf("请输入历史成绩: ");
	scanf("%lf", &(p.data[pos].grade[4]));
	printf("请输入数电成绩: ");
	scanf("%lf", &(p.data[pos].grade[5]));
	printf("请输入体育成绩: ");
	scanf("%lf", &(p.data[pos].grade[6]));


	double sum = p.data[pos].grade[1] + p.data[pos].grade[2] + p.data[pos].grade[3] + p.data[pos].grade[4]
		+ p.data[pos].grade[5] + p.data[pos].grade[6];

	p.data[pos].grade[8] = sum;
	p.data[pos].grade[7] = sum / 6;

}



//打印系统中的内容
void Show(Sys& p)
{
	printf("%-20s\t%-4s\t%-4s\t%-4s\t%-4s\t%-4s\t%-4s\t%-4s\t%-4s\t%-4s\n", "学号", "名字", "高数", "线代", "英语", "历史",
		"数电", "体育", "均分", "总分");

	for (int pos = 0; pos < p.sz; pos++)
	{
		printf("%-20s\t%-4s\t%-4.1lf\t%-4.1lf\t%-4.1lf\t%-4.1lf\t%-4.1lf\t%-4.1lf\t%-4.1lf\t%-4.1lf\n", p.data[pos].num,
			p.data[pos].name,
			p.data[pos].grade[1],
			p.data[pos].grade[2],
			p.data[pos].grade[3],
			p.data[pos].grade[4],
			p.data[pos].grade[5],
			p.data[pos].grade[6],
			p.data[pos].grade[7],
			p.data[pos].grade[8]);
	}

}


//保存学生信息
void Save(Sys& p)
{
	printf("如果想保存班级成绩请输入0,如果想保存全校成绩请输入1\n");

	int in;
	scanf("%s", &in);
	if (in == 0)
	{
		FILE* pf = fopen("ClassOneGrade.txt", "w");
		if (NULL == pf)
		{
			printf("无此文件\n");
		}
		else
		{
			for (int pos = 0; pos < p.sz; pos++)
			{
				fprintf(pf,"%-20s %-4s %-4.1lf %-4.1lf %-4.1lf %-4.1lf %-4.1lf %-4.1lf %-4.1lf %-4.1lf\n", p.data[pos].num,
					p.data[pos].name,
					p.data[pos].grade[1],
					p.data[pos].grade[2],
					p.data[pos].grade[3],
					p.data[pos].grade[4],
					p.data[pos].grade[5],
					p.data[pos].grade[6],
					p.data[pos].grade[7],
					p.data[pos].grade[8]);
			}
			fclose(pf);
			pf = NULL;
			printf("成功保存\n");
			system("start ClassOneGrade.txt");
		}
	}
	else if (in == 1)
	{
		FILE* pf = fopen("SchoolGrade.txt", "w");
		if (NULL == pf)
		{
			printf("无此文件\n");
		}
		else
		{
			for (int pos = 0; pos < p.sz; pos++)
			{
				fprintf(pf, "%-20s %-4s %-4.1lf %-4.1lf %-4.1lf %-4.1lf %-4.1lf %-4.1lf %-4.1lf %-4.1lf\n", p.data[pos].num,
					p.data[pos].name,
					p.data[pos].grade[1],
					p.data[pos].grade[2],
					p.data[pos].grade[3],
					p.data[pos].grade[4],
					p.data[pos].grade[5],
					p.data[pos].grade[6],
					p.data[pos].grade[7],
					p.data[pos].grade[8]);
			}
			fclose(pf);
			pf = NULL;
			printf("成功保存\n");
			system("start SchoolGrade.txt");
		}
	}
}



//导出排名,0班级,1年级
void GetRank(Sys& p, int choice)
{
	for (int j = 0; j < p.sz-1; ++j)
	{
		int exchange = 0;
		for (int i = 1; i < p.sz - j; ++i)
		{
			if (p.data[i - 1].grade[8]< p.data[i].grade[8])
			{
				Stu t = p.data[i - 1];
				p.data[i - 1] = p.data[i];
				p.data[i] = t;
				exchange = 1;
			}
		}

		if (exchange == 0)//当排完一遍都没变化时退出,提高效率
		{
			break;
		}
	}

	
	if (choice == 0)//班级
	{
		int cur = 1;//记录当前排名的位置
		for (int i = 0; i < p.sz; i++)
		{
			if (i == 0 || p.data[i].grade[10] == p.data[i - 1].grade[10])
			{
				p.data[i].grade[9] = cur;
			}
			else
			{
				cur++;
				p.data[i].grade[9] = cur;
			}
		}
		
		FILE* pf = fopen("ClassRank.txt", "w");

		fprintf(pf, "%-20s\t%-4s\t%-4s\t%-4s\t%-4s\t%-4s\t%-4s\t%-4s\t%-4s\t%-4s\t%-4s\n", "学号", "名字", "高数", "线代", "英语", "历史",
			"数电", "体育", "均分", "总分", "校排");
		for (int pos = 0; pos < p.sz; pos++)
		{
			fprintf(pf, "%-20s\t%-4s\t%-4.1lf\t%-4.1lf \t%-4.1lf\t%-4.1lf\t%-4.1lf\t%-4.1lf\t%-4.1lf\t%-4.1lf\t%-4.0lf\n", p.data[pos].num,
				p.data[pos].name,
				p.data[pos].grade[1],
				p.data[pos].grade[2],
				p.data[pos].grade[3],
				p.data[pos].grade[4],
				p.data[pos].grade[5],
				p.data[pos].grade[6],
				p.data[pos].grade[7],
				p.data[pos].grade[8],
				p.data[pos].grade[9]);
		}

		fclose(pf);
		pf = NULL;

		fclose(pf);
		pf = NULL;

		system("start ClassRank.txt");

		
	}
	else if(choice==1)//年级
	{
		int cur = 1;//记录当前排名的位置
		for (int i = 0; i < p.sz; i++)
		{
			if (i == 0 || p.data[i].grade[9] == p.data[i - 1].grade[9])
			{
				p.data[i].grade[9] = cur;
			}
			else
			{
				cur++;
				p.data[i].grade[9] = cur;
			}
		}

		FILE* pf = fopen("SchoolRank.txt", "w");

		fprintf(pf, "%-20s\t%-4s\t%-4s\t%-4s\t%-4s\t%-4s\t%-4s\t%-4s\t%-4s\t%-4s\t%-4s\n", "学号", "名字", "高数", "线代", "英语", "历史",
			"数电", "体育", "均分", "总分","校排");
		for (int pos = 0; pos < p.sz; pos++)
		{
			fprintf(pf, "%-20s\t%-4s\t%-4.1lf\t%-4.1lf \t%-4.1lf\t%-4.1lf\t%-4.1lf\t%-4.1lf\t%-4.1lf\t%-4.1lf\t%-4.0lf\n", p.data[pos].num,
				p.data[pos].name,
				p.data[pos].grade[1],
				p.data[pos].grade[2],
				p.data[pos].grade[3],
				p.data[pos].grade[4],
				p.data[pos].grade[5],
				p.data[pos].grade[6],
				p.data[pos].grade[7],
				p.data[pos].grade[8],
				p.data[pos].grade[9]);
		}

		fclose(pf);
		pf = NULL;
		system("start SchoolRank.txt");
	}


}



int main()
{
	int in = 0;

	//创建通讯录
	Sys system;

	//初始化学生系统
	Init(system);

	//导入初始化数据
	GetData(system);



	do
	{
		menu();
		printf("请选择: ");
		scanf("%d", &in);
		switch (in)
		{
		case 1:
			Add(system);
			break;
		case 2:
			Del(system);
			break;
		case 3:
			Search(system);
			break;
		case 4:
			Modify(system);
			break;
		case 5:
			Show(system);
			break;
		case 6:
			GetGo(system)
			break;
		case 7:
			Save(system);
			break;
		case 8://8
			GetRank(system, 0); //0获取班级Rank
			break;
		case 9://9
			GetRank(system, 1); //1获取年纪Rank
			break;
		case 0:
			Destroy(&system);
			break;
		default:
			printf("选择错误\n");
			break;
		}

	} while (in);

	return 0;
}